`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    01:25:04 05/21/2014 
// Design Name: 
// Module Name:    MontExp 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
//ENCRIPTION.v - This is the encription hardware for project 2.
//
// Created By:	Jesse Inkpen
// Date:	18-February-2014
//
// This module has a three fixed values applied to its input port and waits
// untill a go signal to start calculating an RSA encription block
// Use the define 'BITS to set the bit size of the ENCRIPTION.v synthesis.
///////////////////////////////////////////////////////////////////////////

`define BITS 16

module RSA(
	input						clk,		// clock
	input						go,		// hardware go go go
	input	[`BITS-1:0]		m,		// message
	input	[`BITS-1:0]		e,		// exponent
	input	[`BITS-1:0]		n,		// modulous
	
	output	reg [`BITS-1:0]		r,		// post processing result
	output	reg			d			// done signal
	);
		
	wire ready;
	wire [`BITS-1:0] result;
	reg [`BITS-1:0] A;
	reg [`BITS-1:0] B;
	reg [`BITS-1:0] M;
	reg [`BITS-1:0] z;
	reg start;	
		
	//Instantiate MontProd here
	 MontProd 	MONTPROD(
		.clk(clk),
		.start(start),
		.A(A),
		.B(B),
		.M(M),
		.done(ready),
		.result(result)
	);	
		
		
	parameter NR = `BITS'd857; 					// 16 bit		
//	parameter NR = `BITS'd35790575; 				// 32 bit	
//	parameter NR = `BITS'd288230438294519779; // 64 bit		

	parameter RESET	=	3'b001,
				 COMPUTE	=	3'b010,
				 DISPLAY	=	3'b011;

	reg [2:0] State, NextState;

	//Update State
	always @(posedge clk)
	begin
		if(~go)
			State	<=	RESET;
		else
			State	<=	NextState;
	end
	
	//Next state logic
	always @(*)
	begin
		case (State)
			RESET: 	NextState	= COMPUTE;
			
			
			COMPUTE:	begin
							if(ready == 1)
								NextState	=	DISPLAY;
							else
								NextState	=	COMPUTE;
						end
			
			DISPLAY:	begin
							NextState	= DISPLAY;
						end	
		endcase
	end
		
	//Output logic	
	always @(posedge clk)	
	begin
		case (State)
			RESET:	begin	
							r 		= 0;
							d  	= 0;
							start	= 0;
						end
	
			COMPUTE:	begin	
							A		=	`BITS'd1;
							B		=	NR;
							M		=	n;
							start	=	1;
							
							if(ready == 1)
							begin	
								z = result;
							end
						end
						
			DISPLAY:	begin	
							start = 0;
							r 		= z;
							d	   = 1;
						end	
		endcase
	end
			
endmodule